package com.korion.android.devicedemon.push

import android.util.Log
import com.google.gson.Gson
import com.korion.android.devicedemon.base.JsonUtils
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import org.json.JSONObject
import java.lang.Exception
import java.util.concurrent.TimeUnit


class PushImpl : PushAPI {

    companion object {
        private const val TAG = "Push"
        private const val HTTP_OK = 200

        val sImpl = PushImpl()
    }

    private val client: OkHttpClient = OkHttpClient.Builder()
        .connectTimeout(3000, TimeUnit.MILLISECONDS)
        .build()

    /**
     * docs:
     * https://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal
     *
     * example:
     * curl -i -H "Content-type: application/json;charset=utf-8" \
     * -X POST \
     * -d '{"app_id":"cli_xxxxxxxxxxxxxx","app_secret":"xxxxxxxxxxxxxxxxxxx"}' \
     * https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
     *
     * response:
     * {"code":0,"expire":4296,"msg":"ok","tenant_access_token":"t-xxxxxxxxxxxxxx"}
     */
    override fun getAccessToken(appId: String, appSecret: String): AccessTokenModel? {
        val mediaType = "application/json;charset=utf-8".toMediaTypeOrNull()
        val json = mapOf<String, String>(
            "app_id" to appId,
            "app_secret" to appSecret
        ).let { JSONObject(it) }
        val body: RequestBody = RequestBody.create(mediaType, json.toString())
        val request = Request.Builder()
            .url("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal")
            .post(body)
            .build()
        val resp = client.newCall(request).execute()
        if (resp.code == HTTP_OK) {
            val data = resp.body?.string()
            Log.d(TAG, "getAccessToken: $data")
            try {
                return JsonUtils.fromJson<AccessTokenModel>(data, AccessTokenModel::class.java)
            } catch (e: Exception) {
                Log.e(TAG, "server response error:$data", e)
            }
        } else {
            Log.e(TAG, "failed to connect server, http status=${resp.code}")
        }
        return null
    }

    /**
     * docs:https://open.feishu.cn/document/server-docs/im-v1/message/create
     *
     * curl -i -H "Content-type: application/json;charset=utf-8" \
     * -H "Authorization: Bearer t-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     * -X POST  \
     * -d '{ "receive_id": "xxxxxxxxxxxxxxxxx", "msg_type": "text", "content": "{\"text\":\"test content\"}", "uuid": "" }' \
     * https://open.feishu.cn/open-apis/im/v1/messages\?receive_id_type\=open_id
     *
     * response:
     * {
     *     "code": 0,
     *     "data": {
     *         "body": {
     *             "content": "{\"text\":\"test content\"}"
     *         },
     *         "chat_id": "",
     *         "create_time": "",
     *         "deleted": false,
     *         "message_id": "",
     *         "msg_type": "text",
     *         "sender": {
     *             "id": "",
     *             "id_type": "app_id",
     *             "sender_type": "app",
     *             "tenant_key": ""
     *         },
     *         "update_time": "",
     *         "updated": false
     *     },
     *     "msg": "success"
     * }
     */
    override fun pushTextMessage(accessToken: String, openId: String, message: String): BaseModel? {
        val mediaType = "application/json;charset=utf-8".toMediaTypeOrNull()
        val json = mapOf<String, String>(
            "receive_id" to openId,
            "msg_type" to "text",
            "content" to JSONObject().apply {
                put("text", message)
            }.toString()
        ).let { JSONObject(it) }
        val body: RequestBody = RequestBody.create(mediaType, json.toString())
        val request = Request.Builder()
            .url("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id")
            .header("Authorization", "Bearer $accessToken")
            .post(body)
            .build()
        val resp = client.newCall(request).execute()
        if (resp.code == HTTP_OK) {
            val data = resp.body?.string()
            try {
                return JsonUtils.fromJson<BaseModel>(data, BaseModel::class.java)
            } catch (e: Exception) {
                Log.e(TAG, "server response error:$data")
            }
        } else {
            Log.e(TAG, "failed to connect server, http status=${resp.code}")
        }
        return null
    }

//    /**
//     * docs: https://open.feishu.cn/document/faq/trouble-shooting/how-to-obtain-openid
//     *
//     * example:
//     * curl -i -X POST 'https://fsopen.bytedance.net/open-apis/contact/v3/users/batch_get_id?user_id_type=open_id' \
//     * -H 'Content-Type: application/json' \
//     * -H 'Authorization: Bearer t-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
//     * -d '{
//     * 	"emails": [],
//     * 	"mobiles": [
//     * 		"phone_number"
//     * 	]
//     * }'
//     *
//     * response:
//     * {"code":0,"data":{"user_list":[{"mobile":"phone_number","user_id":"xxxxxxxxxxxxxxxxxxxxxxxxxx"}]},"msg":"success"}
//     */
//    fun getPushOpenId(phone: String, ) {
//
//    }

}